import pandas as pd
# 5.2 随机森林
# 忽略UndefinedMetricWarning警告
from sklearn.exceptions import UndefinedMetricWarning
import warnings
warnings.filterwarnings(action='ignore', category=UndefinedMetricWarning)
# 主要是为了导入GridSearchCV（开销太大了，超级耗时，想哭~）
import sklearn.model_selection as ms
from sklearn.model_selection import RandomizedSearchCV  # 导入“随机搜索”
from sklearn.metrics import classification_report  # 导入文本报告

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
import joblib # 用于保存和提取模型


best_train = pd.read_csv(r'./data/特征工程/best_train.csv')
best_test = pd.read_csv(r'./data/特征工程/best_test.csv')

# 特征
x = best_train
# 训练集对应的标签
labeldf = pd.read_csv(r'./data/label.csv')
y = labeldf['是否流失']

# 划分训练集和测试集
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size = 0.25)

# print('正在处理中 model，请稍后...')
# # 设置算法参数
# deal_params = {'n_estimators':[ x for x in range(50,1050,50)]}
# # 设置随机森林分类模型
# RFC = RandomForestClassifier(criterion = 'gini',bootstrap=True,n_jobs = -1,random_state = 2022)
# # 因为用的是分类器，所以这里的评估指标scoring要用分类任务的评价标准
# # gridsearchcv优化
# model = ms.GridSearchCV(RFC,deal_params,cv = 5,scoring='roc_auc',error_score='raise')
# # 随机搜索参数优化
# # model = RandomizedSearchCV(RFC,deal_params,n_iter = 100,cv = 5,scoring = 'roc_auc',error_score='raise',random_state = 2022,n_jobs = -1)
# model.fit(x_train,y_train)
# print(f'当前最佳参数{model.best_params_}')
# print(f'当前最佳分数{model.best_score_}')
# print('处理成功~')

# print('正在处理中 model1，请稍后...')
# # 设置算法参数
# deal_params1 = {'max_depth':[x for x in range(10,110,10)]}
# # 设置随机森林分类模型
# RFC1 = RandomForestClassifier(n_estimators = 800,criterion = 'gini',bootstrap=True,n_jobs = -1,random_state = 2022)
# # 因为用的是分类器，所以这里的评估指标scoring要用分类任务的评价标准
# # gridsearchcv优化
# model1 = ms.GridSearchCV(RFC1,deal_params1,cv = 5,scoring='roc_auc',error_score='raise')
# # 随机搜索参数优化
# # model = RandomizedSearchCV(RFC,deal_params,n_iter = 100,cv = 5,scoring = 'roc_auc',error_score='raise',random_state = 2022,n_jobs = -1)
# model1.fit(x_train,y_train)
# print(f'当前最佳参数{model1.best_params_}')
# print(f'当前最佳分数{model1.best_score_}')
# print('处理成功~')

# print('正在处理中model2，请稍后...')
# # 设置算法参数
# deal_params2 = {'min_samples_split':[x for x in range(2,11,1)]}
# # 设置随机森林分类模型
# RFC2 = RandomForestClassifier(n_estimators = 800,max_depth = 60,criterion = 'gini',bootstrap=True,n_jobs = -1,random_state = 2022)
# # 因为用的是分类器，所以这里的评估指标scoring要用分类任务的评价标准
# # gridsearchcv优化
# model2 = ms.GridSearchCV(RFC2,deal_params2,cv = 5,scoring='roc_auc',error_score='raise')
# # 随机搜索参数优化
# # model = RandomizedSearchCV(RFC,deal_params,n_iter = 100,cv = 5,scoring = 'roc_auc',error_score='raise',random_state = 2022,n_jobs = -1)
# model2.fit(x_train,y_train)
# print(f'当前最佳参数{model2.best_params_}')
# print(f'当前最佳分数{model2.best_score_}')
# print('处理成功~')

print('正在处理中 model3，请稍后...')
# 设置算法参数
deal_params3 = {'min_samples_leaf':[x for x in range(1,11,1)]}
# 设置随机森林分类模型
RFC3 = RandomForestClassifier(n_estimators = 800,max_depth = 60,min_samples_split = 2,criterion = 'gini',bootstrap=True,n_jobs = -1,random_state = 2022)
# 因为用的是分类器，所以这里的评估指标scoring要用分类任务的评价标准
# gridsearchcv优化
model3 = ms.GridSearchCV(RFC3,deal_params3,cv = 5,scoring='roc_auc',error_score='raise')
# 随机搜索参数优化
# model = RandomizedSearchCV(RFC,deal_params,n_iter = 100,cv = 5,scoring = 'roc_auc',error_score='raise',random_state = 2022,n_jobs = -1)
print("训练model3")
model3.fit(x_train,y_train)
print(f'当前最佳参数{model3.best_params_}')
print(f'当前最佳分数{model3.best_score_}')
print('处理成功~')

# 5.2.1 训练结果
# 查看最佳分数
print(model3.best_score_)
# 查看最佳参数
print(model3.best_params_)
# 查看分类指标文本报告
rfc_pred = model3.predict(x_test)
print(classification_report(y_test,rfc_pred))

# 保存最佳模型
best_model = model3.best_estimator_
joblib.dump(best_model,r'./data/建模/rfc.pkl')

# 读取模型
rfc_model = joblib.load(r'./data/建模/rfc.pkl')

# 5.2.2 模型应用
# 利用最佳模型进行预测
rfc_pred = rfc_model.predict(best_test)

# 制作符合提交要求的submit
iddf = pd.read_csv(r'./data/ID.csv')
test_id = iddf.iloc[150000:,:]
rfc_submit = pd.DataFrame({'客户ID':test_id['客户ID'],'是否流失':rfc_pred})
rfc_submit.to_csv(r'./data/预测结果/rfc_submit.csv',index = False,encoding = 'utf-8')
rfc_submit.head()




